class DebuggerService {
    constructor() {
        this.requiredVersion = '1.2';
        this.target = null;
        chrome.debugger.onDetach.addListener(this.onDetach);
        chrome.debugger.onEvent.addListener(this.onEvent);
    }

    onEvent(source, method, params) {
        console.log(source, method, params, 'onEvent-----------');
    }

    onDetach(source, reason) {
        this.target = null;
    }

    getTargetsPromise() {
        return new Promise((resolve) => {
            chrome.debugger.getTargets(resolve);
        });
    }

    // 再次attach同一个target会报错
    // 再次target其他target会成功（不用先detach掉）
    attachPromise(target) {
        return new Promise((resolve) => {
            chrome.debugger.attach(target, this.requiredVersion, () => {
                if (chrome.runtime.lastError) {
                    resolve({
                        success: false,
                        errMsg: chrome.runtime.lastError,
                    });
                } else {
                    resolve({
                        success: true,
                        errMsg: '成功',
                    });
                }
            });
        });
    }

    detachPromise(target) {
        return new Promise((resolve) => {
            chrome.debugger.detach(target, () => {
                if (chrome.runtime.lastError) {
                    resolve({
                        success: false,
                        errMsg: chrome.runtime.lastError,
                    });
                } else {
                    resolve({
                        success: true,
                        errMsg: '成功',
                    });
                }
            });
        });
    }

    // 执行'Runtime.evaluate'
    runtimeEvaluatePromise(target, code) {
        return new Promise((resolve) => {
            const method = 'Runtime.evaluate';
            const commandParams = {
                expression: String(code),
            };
            chrome.debugger.sendCommand(target, method, commandParams, (result) => {
                if (chrome.runtime.lastError) {
                    resolve({
                        success: false,
                        errMsg: chrome.runtime.lastError,
                        target,
                    });
                } else {
                    resolve({
                        success: true,
                        result,
                        target,
                    });
                }
            });
        });
    }

    // 执行code脚本
    async runtimeEvaluateAsync(code) {
        if (!this.target) {
            const serviceWorkerUrl = chrome.runtime.getURL('service_worker.js');
            const targets = await this.getTargetsPromise();
            this.target = targets.find((t) => t.url === serviceWorkerUrl);
            await this.attachPromise({ targetId: this.target.id });
        }
        const res = await this.runtimeEvaluatePromise({ targetId: this.target.id }, code);
        return res;
    }

    // 生成function
    async generateFunc(code, funcName) {
        if (!funcName) {
            funcName = `func_${crypto.randomUUID().replace(/-/g, '')}`;
        }
        const funcContent = `(() => { 
            globalThis['${funcName}']=()=>{${code}}
        })();`;
        const res = await this.runtimeEvaluateAsync(funcContent);
        const func = globalThis[funcName];
        if (func && funcName !== 'injectCodeToContent') {
            // 使用过立即删除
            delete globalThis[funcName];
        }
        return func;
    }
}

globalThis.debuggerService = new DebuggerService();
